<template>
  <a-card :bordered="false">
    <div class="table-page-search-wrapper">
      <a-form layout="inline">
        <a-row :gutter="48">
          <a-col :md="8" :sm="24">
            <a-form-item label="商品名称">
              <a-input v-model="queryParam.name" placeholder=""/>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="商品编号">
              <a-input v-model="queryParam.numbering" placeholder=""/>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="活动编号">
              <a-input v-model="queryParam.activity_numbering" placeholder=""/>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="商品类别">
              <commodity-category-selection v-model="queryParam.category"></commodity-category-selection>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="商品标签">
              <activity-label-selection v-model="queryParam.label"></activity-label-selection>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="更新时间">
              <a-range-picker :allowClear="true" :defaultValue="updatedAtRange" ref="updatedAtRangePicker" @change="updatedAtRangePickerOnChange"/>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="状态">
              <a-select v-model="queryParam.status" placeholder="请选择" default-value="">
                <a-select-option value="">全部</a-select-option>
                <a-select-option value="1">已上架</a-select-option>
                <a-select-option value="2">已下架</a-select-option>
                <a-select-option value="3">已结束</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="是否激活">
              <a-select v-model="queryParam.locking" placeholder="请选择" default-value="">
                <a-select-option value="">全部</a-select-option>
                <a-select-option value="1">激活</a-select-option>
                <a-select-option value="2">锁定</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="活动抢购开始时间">
              <a-range-picker :allowClear="true" ref="commodityActivityPanicBuyingTimeRangePicker" @change="commodityActivityPanicBuyingTimeRangeChange"/>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <span class="table-page-search-submitButtons">
              <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
              <a-button style="margin-left: 8px" @click="handleReset">重置</a-button>
              <a-button style="margin-left: 8px" @click="handleExport">导出</a-button>
              <a-button style="margin-left: 8px" @click="handleExport(true)">大数据导出</a-button>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>

    <div class="table-operator">
      <a-button type="primary" icon="plus" @click="() => {this.$router.push('/commodity/live-today/create')}">新建</a-button>
      <a-button @click="() => exportCurrentPageInvoice()">导出当页发货单</a-button>
      <a-button @click="() => exportCurrentPageStock()">导出当页备货单</a-button>
      <a-button @click="exportLockingBatchTemplate" type="link">批量锁定或激活模板</a-button>
      <progress-time-line
        title="批量锁定或激活"
        btn-title="批量锁定或激活"
        :steps="[{ title: '读取文件'}, { title: '上传处理'}, { title: '完成' }]"
        :handle-raw="handleLockingBatch"
      />
    </div>

    <s-table
      ref="table"
      rowKey="id"
      :columns="columns"
      :data="loadData"
      :pageNum="parseInt(queryParam.page || 1)"
      :pageSize="parseInt(queryParam.per_page || 20)"
      showPagination="auto"
      :scroll="{ x: 1500 }"
    >
      <span slot="name" slot-scope="text, record">
        <a-row type="flex">
          <a-col span="12">
            <img
              v-if="record.attachments[0]"
              width="100px"
              :src="record.attachments[0].url"
            />
            <img
              v-if="record.labels[0] && record.labels[0].attachments[0]"
              width="50px"
              :src="record.labels[0].attachments[0].url"
              style="position: absolute; left: 0; top: 0;"
            />
          </a-col>
          <a-col span="11">
            <a-row :gutter="[24, 32]">
              <a-col>{{ record.commodity.name }}</a-col>
              <a-col style="color: #8d8d8d">{{ record.commodity.numbering }}</a-col>
            </a-row>
          </a-col>
        </a-row>
      </span>

      <span slot="action" slot-scope="text, record">
        <template>
          <a @click="() => $router.push({ name: 'commodity_activity_live_today_info', params: { id: record.id } })">详情</a>

          <a-divider type="vertical"/>

          <a @click="() => $router.push({ name: 'commodity_activity_live_today_edit', params: { id: record.id } })">编辑</a>

          <a-divider type="vertical"/>

          <a-dropdown>
            <a class="ant-dropdown-link" @click="e => e.preventDefault()">
              操作
            </a>
            <a-menu slot="overlay">
              <a-menu-item>
                <a
                  @click="() => $router.push({
                    name: 'commodity_activity_live_today_moments_material',
                    params: { id: record.id }
                  })"
                >朋友圈素材</a>
              </a-menu-item>
              <a-menu-item>
                <a
                  @click="() => $router.push({
                    name: 'commodity_activity_live_today_forward_material',
                    params: { id: record.id }
                  })"
                >转发素材</a>
              </a-menu-item>
              <a-menu-item>
                <a @click="handleStockingExport(record)">导出备货单</a>
              </a-menu-item>
              <a-menu-item>
                <a @click="handleInvoiceExport(record)">导出发货单</a>
              </a-menu-item>
              <a-menu-item>
                <a-popconfirm placement="top" @confirm="handleLocking(record)">
                  <template slot="title">
                    确定要{{ lockingActionMap[record.locking]['text'] }}吗?
                  </template>
                  <a>{{ lockingActionMap[record.locking]['text'] }}</a>
                </a-popconfirm>
              </a-menu-item>
              <a-menu-item>
                <a-popconfirm placement="top" @confirm="handleStatus(record)">
                  <template slot="title">
                    确定要{{ statusActionMap[record.status]['text'] }}吗?
                  </template>
                  <a>{{ statusActionMap[record.status]['text'] }}</a>
                </a-popconfirm>
              </a-menu-item>
              <a-menu-item>
                <a
                  @click="() => $router.push({
                    name: 'commodity_activity_live_today_copy',
                    params: { id: record.id },
                    query: { copy: 1 }
                  })"
                >复制活动</a>
              </a-menu-item>
              <a-menu-item>
                <a
                  @click="e => handleDelete(record)"
                >删除</a>
              </a-menu-item>
            </a-menu>
          </a-dropdown>
        </template>
      </span>

      <a-table
        rowKey="id"
        slot="expandedRowRender"
        slot-scope="record"
        :columns="innerColumns[record.id]"
        :data-source="innerData[record.id]"
        :pagination="false"
      >
        <template slot="stock" slot-scope="_item">
          <editable-cell :text="parseInt(_item.stock || 0)" @change="onSkuStockChange(_item.id, 'stock', $event, record.id)"/>
        </template>
      </a-table>
    </s-table>
  </a-card>
</template>

<script>
import moment from 'moment'
import { Ellipsis, STable } from '@/components'
import CommodityCategorySelection from '@/components/CommodityCategorySelection/CommodityCategorySelection'
import SupplierSelect from '@/components/SupplierSelect/SupplierSelect'
import {
  commodityActivityLiveTodayUpdateLocking,
  commodityActivityLiveTodayUpperAndLowerShelves,
  deleteCommodityActivityLiveToday,
  getCommodityActivityLiveTodayList,
  liveTodayInvoiceExport,
  liveTodayStockingExport,
  updateLiveTodaySku
} from '@/api/commodity'
import ActivityLabelSelection from '@/components/ActivityLabelSelection/ActivityLabelSelection'
import pick from 'lodash.pick'
import cloneDeep from 'lodash.clonedeep'
import { formatAmount } from '@/utils/util'
import EditableCell from '@/components/EditableCell/EditableCell'
import ProgressTimeLine from '@/components/ProgressTimeLine/ProgressTimeLine'
import XLSX from 'xlsx'

const LOCKING_MAP = {
    1: '激活',
    2: '锁定'
  }

  const LOCKING_ACTION_MAP = {
    1: {
      text: '锁定',
      action: 2
    },
    2: {
      text: '激活',
      action: 1
    }
  }

  const STATUS_MAP = {
    1: '已上架',
    2: '已下架'
  }

  const STATUS_ACTION_MAP = {
    1: {
      text: '下架',
      action: 2
    },
    2: {
      text: '上架',
      action: 1
    }
  }

  export default {
    name: 'List',
    components: {
      ProgressTimeLine,
      EditableCell,
      ActivityLabelSelection,
      SupplierSelect,
      CommodityCategorySelection,
      STable,
      Ellipsis
    },
    created () {
      this.queryParam = cloneDeep(this.$route.query)
      this.queryParam.category && (this.queryParam.category = parseInt(this.queryParam.category))
      this.queryParam.label && (this.queryParam.label = parseInt(this.queryParam.label))
      if (this.queryParam.updated_at_begin && this.queryParam.updated_at_end) {
        this.updatedAtRange = [moment(this.queryParam.updated_at_begin), moment(this.queryParam.updated_at_end)]
      }
    },
    data () {
      return {
        mdl: {},
        // 查询参数
        queryParam: {},
        updatedAtRange: null,
        // 表头
        columns: [
          {
            title: '活动编号',
            width: '80px',
            dataIndex: 'numbering'
          },
          {
            title: '活动名称',
            width: '100px',
            dataIndex: 'name'
          },
          {
            title: '商品名称',
            width: '220px',
            scopedSlots: { customRender: 'name' }
          },
          {
            title: '商品类别',
            width: '90px',
            dataIndex: 'commodity.category.name'
          },
          {
            title: '总销量',
            width: '100px',
            customRender: record => record.skus.reduce((total, curr) => total + curr.sales, 0)
          },
          {
            title: '可销售库存',
            width: '110px',
            customRender: record => record.skus.reduce((total, curr) => total + curr.stock, 0)
          },
          {
            title: '抢购时间',
            width: '200px',
            customRender: item => `${item.panic_buying_start_time}\n至\n${item.panic_buying_end_time}`
          },
          {
            title: '锁单',
            width: '80px',
            dataIndex: 'locking',
            customRender: locking => LOCKING_MAP[locking]
          },
          {
            title: '状态',
            width: '80px',
            customRender: item => {
              return moment().isAfter(moment(item.panic_buying_end_time)) ? '已结束' : STATUS_MAP[item.status]
            }
          },
          {
            title: '供应商',
            dataIndex: 'commodity.supplier.name',
            width: '80px'
          },
          {
            title: '更新时间',
            width: '150px',
            dataIndex: 'updated_at'
          },
          {
            title: '操作',
            dataIndex: 'action',
            width: '150px',
            scopedSlots: { customRender: 'action' }
          }
        ],
        // 加载数据方法 必须为 Promise 对象
        firstLoadData: true,
        loadData: parameter => {
          this.queryParam.type = 1

          let query = null
          if (this.firstLoadData) { // 第一次加载数据,需要以 router query 为准
            this.firstLoadData = false
            query = cloneDeep(Object.assign(parameter, this.queryParam))
          } else {
            query = cloneDeep(Object.assign(this.queryParam, parameter))
          }
          try {
            // 把搜索条件放入 query
            this.$router.push({ path: this.$route.fullPath, query })
          } catch (e) {
          }

          return new Promise(resolve => {
            getCommodityActivityLiveTodayList(query).then(res => {
              res.data.forEach(item => {
                this.innerColumns[item.id] = this.expandedRowRenderColumns(item)
                this.innerData[item.id] = this.expandedRowRenderData(item)
              })

              this.currentListData = res.data // 当前页,用于处理导出当前页发货单
              this.currentPage = res.current_page
              resolve(res)
            })
          })
        },
        selectedRowKeys: [],
        selectedRows: [],
        statusActionMap: STATUS_ACTION_MAP,
        lockingActionMap: LOCKING_ACTION_MAP,
        innerColumns: {},
        innerData: {},
        currentPage: 1,
        currentListData: []
      }
    },
    methods: {
      updatedAtRangePickerOnChange (date, dateString) {
        this.queryParam.updated_at_begin = dateString[0]
        this.queryParam.updated_at_end = dateString[1]
      },
      handleEdit (record) {
        this.$refs.modal.edit(record)
      },
      handleOk () {
        this.$refs.table.refresh()
      },
      onSelectChange (selectedRowKeys, selectedRows) {
        this.selectedRowKeys = selectedRowKeys
        this.selectedRows = selectedRows
      },
      resetSearchForm () {
        this.queryParam = {
          date: moment(new Date())
        }
      },
      handleReset () {
        this.queryParam = {}
        this.$router.push({ query: {} })
        this.$refs.updatedAtRangePicker.$refs.picker.clearSelection(new MouseEvent('click'))
        this.$refs.commodityActivityPanicBuyingTimeRangePicker.$refs.picker.clearSelection(new MouseEvent('click'))
        this.$refs.table.refresh(true)
      },
      handleDelete (record) {
        const { $refs, $message } = this
        if (record.status === 1) {
          $message.error('活动还未下架,不能删除')
          return
        }

        this.$confirm({
          title: '确定要删除吗',
          onOk () {
            return new Promise((resolve, reject) => {
              deleteCommodityActivityLiveToday(record.id)
                .then(res => {
                  $refs.table.refresh()
                  $message.success('删除成功')
                  resolve()
                })
                .catch(err => {
                  reject(err)
                })
            })
          }
        })
      },
      handleStatus (record) {
        commodityActivityLiveTodayUpperAndLowerShelves(record.id, STATUS_ACTION_MAP[record.status]['action']).then(res => this.$refs.table.refresh())
      },
      handleLocking (record) {
        commodityActivityLiveTodayUpdateLocking(record.id, LOCKING_ACTION_MAP[record.locking]['action']).then(res => this.$refs.table.refresh())
      },
      handleExport (isAsync = false) {
        const exportParam = { export: true }
        ;(isAsync === true) && Object.assign(exportParam, { async: true })

        getCommodityActivityLiveTodayList(Object.assign(exportParam, this.queryParam)).then(_ => {
          (isAsync === true) && this.$notification.success({ message: '添加任务成功,请关注[系统-异步导出任务]' })
        })
      },
      handleStockingExport (record) {
        liveTodayStockingExport(record.id)
      },
      handleInvoiceExport (record) {
        liveTodayInvoiceExport(record.id)
      },
      /**
       * 整理 SKU 的表头
       */
      expandedRowRenderColumns (record) {
        const skuColumns = [
          {
            title: '入仓价（元）',
            dataIndex: 'entry_price'
          },
          {
            title: '进价（元）',
            dataIndex: 'purchase_price'
          },
          {
            title: '大咖价（元）',
            dataIndex: 'strongman_price'
          },
          {
            title: '精英价（元）',
            dataIndex: 'elite_price'
          },
          {
            title: '群主价（元）',
            dataIndex: 'group_owner_price'
          },
          {
            title: '直接奖励（元）',
            dataIndex: 'direct_invitation'
          },
          {
            title: '间接奖励（元）',
            dataIndex: 'indirect_invitation'
          },
          {
            title: '对外价格（元）',
            dataIndex: 'external_guide_price'
          },
          {
            title: '发布量',
            customRender: (index, item) => {
              return parseInt((item.stock || 0)) + parseInt((item.sales || 0))
            }
          },
          {
            title: '销售量',
            customRender: (index, item) => {
              return parseInt(item.sales || 0)
            }
          },
          {
            title: '库存',
            scopedSlots: { customRender: 'stock' }
          }
          // {
          //   title: '预计销量', // 已废弃
          //   dataIndex: 'estimated_sales'
          // }
        ]

        record.attributes.reverse().forEach(attribute => skuColumns.unshift({
          'title': attribute.name,
          dataIndex: attribute.id
        }))

        return skuColumns
      },
      /**
       * 整理 SKU 数据
       * @param record
       */
      expandedRowRenderData (record) {
        const skuData = []
        record.skus.reverse().forEach(sku => {
          // sku 系统字段
          const sysField = pick(
            sku,
            [ 'id', 'direct_invitation', 'elite_price', 'entry_price', 'external_guide_price',
              'group_owner_price', 'indirect_invitation', 'strongman_price', 'purchase_price', 'sales', 'stock'
              // 'estimated_sales' // 已废弃
            ]
          )
          // 格式化
          Object.keys(sysField).forEach(field => {
            if ([
              'id', 'stock', 'sales'
              // 'estimated_sales' // 已废弃
            ].includes(field)) {
              return
            }
            sysField[field] = formatAmount(sysField[field])
          })
          sysField.amount = sku.amount
          // sku 自定义数据
          sku.values.forEach(value => {
            sysField[value.attribute_id] = value.content
          })

          skuData.push(sysField)
        })

        return skuData
      },
      /**
       * SKU 库存编辑
       * @param id
       * @param dataIndex
       * @param value
       * @param recordId
       */
      onSkuStockChange (id, dataIndex, value, recordId) {
        const sourceData = [...this.innerData[recordId]]
        const target = sourceData.find(item => item.id === id)
        if (target) {
          // 这里好评返团用直播接口也没问题, sku id 通用的
          updateLiveTodaySku(id, { stock: value })
            .then(res => {
              target[dataIndex] = value
              const innerDataTemp = cloneDeep(this.innerData)
              innerDataTemp[recordId] = sourceData
              // 列表刷新问题, 这里粗暴解决
              this.innerData = []
              this.innerData = innerDataTemp

              this.$notification.success({ message: '操作成功!' })
            })
        }
      },
      /**
       * 导出本页发货单
       */
      exportCurrentPageInvoice () {
        const currentListData = cloneDeep(this.currentListData)
        const currentPage = cloneDeep(this.currentPage)

        this.$notification.info({ message: `开始导出第${currentPage}页发货单` })
        if (currentListData.length > 0) {
          const processHandler = setInterval(_ => {
            const item = currentListData.shift()

            this.$notification.info({ message: `开始导出活动编号: ${item.numbering} 发货单` })
            this.handleInvoiceExport(item)

            if (currentListData.length <= 0) {
              clearInterval(processHandler)
              this.$notification.info({ message: `结束导出第${currentPage}页发货单` })
            }
          }, 3000)
        }
      },
      /**
       * 导出本页发货单
       */
      exportCurrentPageStock () {
        const currentListData = cloneDeep(this.currentListData)
        const currentPage = cloneDeep(this.currentPage)

        this.$notification.info({ message: `开始导出第${currentPage}页备货单` })
        if (currentListData.length > 0) {
          const processHandler = setInterval(_ => {
            const item = currentListData.shift()

            this.$notification.info({ message: `开始导出活动编号: ${item.numbering} 备货单` })
            this.handleStockingExport(item)

            if (currentListData.length <= 0) {
              clearInterval(processHandler)
              this.$notification.info({ message: `结束导出第${currentPage}页备货单` })
            }
          }, 3000)
        }
      },
      /**
       * 批量锁定/解锁模板
       */
      exportLockingBatchTemplate () {
        const ws = XLSX.utils.aoa_to_sheet([
          ['活动编号', '锁定或激活'],
          ['Z01630', '激活'],
          ['Z01629', '锁定']
        ])
        const wb = XLSX.utils.book_new()
        XLSX.utils.book_append_sheet(wb, ws, 'SheetJS')
        XLSX.writeFile(wb, '批量锁定或激活模板.xlsx')
      },
      handleLockingBatch (item, timeline) {
        const lockingMap = {
          '激活': 1,
          '锁定': 2
        }

        return new Promise(resolve => {
          try {
            if (item['活动编号'] === undefined) {
              throw new Error('缺失活动编号')
            }
            if (!lockingMap.hasOwnProperty(item['锁定或激活'])) {
              throw new Error('锁定或激活类型错误')
            }

            commodityActivityLiveTodayUpdateLocking(item['活动编号'], lockingMap[item['锁定或激活']]).then(res => {
              timeline.push({
                color: 'green',
                content: [
                  '活动编号: ' + item['活动编号'] + `(${item['锁定或激活']})`
                ]
              })
              resolve()
            }).catch(e => {
              timeline.push({
                color: 'red',
                content: [
                  '活动编号: ' + item['活动编号'] + `(${item['锁定或激活']})`,
                  e.message || ''
                ]
              })
            })
          } catch (e) {
            timeline.push({
              color: 'red',
              content: [
                '活动编号: ' + item['活动编号'] + `(${item['锁定或激活']})`,
                e.message || ''
              ]
            })
          }
        })
      },
      commodityActivityPanicBuyingTimeRangeChange (date, dateString) {
        this.queryParam.panic_buying_start_time = dateString[0]
        this.queryParam.panic_buying_end_time = dateString[1]
      }
    }
  }
</script>
